import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart' hide RefreshCallback;
import 'package:flutter/widgets.dart';
import 'SliverListView.dart';

const double _defaultEndReachedTriggerDistance = 10;

class SliverScrollView extends StatefulWidget {
  SliverScrollView({
    Key key, 
    this.sliver,
    this.child, 
    this.renderRefresh = CupertinoSliverRefreshControl.buildSimpleRefreshIndicator, 
    this.onRefresh, 
    this.refreshIndicatorExtent = _defaultRefreshIndicatorExtent, 
    this.refreshTriggerPullDistance = _defaultRefreshTriggerPullDistance, 
    this.onEndReached, 
    this.endReachedTriggerDistance = _defaultEndReachedTriggerDistance, 
    this.footer, 
    this.onEndReachedStateChange, 
    this.backgroundColor = Colors.transparent,
    this.hasHeader = false,
    this.physics,
  }) :
   assert(child == null || sliver == null, "不能同时传递child和sliver子组件"),
   super(key: key);

  /// 子组件
  final Widget child;
  /// sliver子组件
  final Widget sliver;
   /// 渲染下拉刷新器 可选
  final RefreshControlIndicatorBuilder renderRefresh;
  /// 触发刷新事件 异步 可选
  final RefreshCallback onRefresh;
  /// 触发refresh零界点
  final double refreshIndicatorExtent;
  /// 触发refresh指示器的零界点
  final double refreshTriggerPullDistance;
  /// 触发上拉加载事件
  final EndReachedCallback onEndReached;
  // 触发endReached的零界点
  final double endReachedTriggerDistance;
  /// 列表尾部 可以渲染上拉加载组件
  final Widget footer;
  /// 状态变更
  final EndReachedStateChange onEndReachedStateChange;
  /// 列表背景色，默认为透明色
  final Color backgroundColor;
  /// 是否有头部导航
  final bool hasHeader;
  /// 滚动条物理行为
  final ScrollPhysics physics;

  static const double _defaultRefreshTriggerPullDistance = 100.0;
  static const double _defaultRefreshIndicatorExtent = 60.0;

  static SliverListViewState of(BuildContext context){
    return context.dependOnInheritedWidgetOfExactType<SliverListViewState>();
  }

  _SliverScrollViewState createState() => _SliverScrollViewState();
}

class _SliverScrollViewState extends State<SliverScrollView> {
  EndReachedState reachedState = EndReachedState.inactive;


  @override
  Widget build(BuildContext context) {
    return SliverListViewState(
      reachedState: reachedState,
      context: context,
      child: CupertinoPageScaffold(
        backgroundColor: widget.backgroundColor,
        child: EndReachedNotificationListenerBuilder (
          onEndReached: widget.onEndReached,
          onEndReachedStateChange: (_state) {
            if(widget.onEndReachedStateChange != null) widget.onEndReachedStateChange(_state);
            this.setState(() {
              reachedState = _state;
            });
          },
          child: CustomScrollView(
            physics: widget.physics != null ? widget.physics : widget.onRefresh != null ? BouncingScrollPhysics() : ClampingScrollPhysics(),
            slivers: <Widget>[
                widget.onRefresh !=null ? CupertinoSliverRefreshControl(
                  builder: widget.renderRefresh,
                  refreshIndicatorExtent: widget.refreshIndicatorExtent,
                  refreshTriggerPullDistance: widget.refreshTriggerPullDistance,
                  onRefresh: widget.onRefresh,
                ) : null,
                SliverSafeArea(
                  top: widget.hasHeader, // Top safe area is consumed by the navigation bar.
                  bottom: widget.footer == null,
                  sliver: widget.sliver == null ? SliverToBoxAdapter(
                    child: Container(
                      child: widget.child,
                    )
                  ) : widget.sliver,
                ),
                widget.footer == null ? null : SliverSafeArea(
                  top: false,
                  bottom: true,
                  sliver: widget.footer,
                ),
            ].where((item)=> item != null).toList(),
          ),
        )
      ),
    );
  }
}